home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / ym_utils / cd_link.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-08  |  5.1 KB  |  227 lines

  1. /* UnIX CD-ROM symbolic link utility  by
  2.         Matthew B. Hornbeck, Director of Technical Services
  3.         Copyright 1989 by Young Minds, Incorporated
  4.         June 19, 1989.
  5. File : CD_LINK.C
  6. */
  7.  
  8. #ifdef sun
  9. #define REALPATH
  10. #endif
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <ctype.h>
  15. #include <malloc.h>
  16.  
  17. #ifdef REALPATH
  18. #include <sys/param.h>
  19. #else
  20. #define MAXPATHLEN    1024
  21. #endif
  22.  
  23. #define FALSE    0
  24. #define TRUE    !FALSE
  25.  
  26. char *prog_name (program_name)
  27. char *program_name;
  28.  
  29. {    unsigned int len;
  30.  
  31.     len = strlen (program_name) - 1;
  32.     program_name = program_name + len;
  33.     while ((len != 0) && (*program_name != '/'))
  34.       {    program_name --;
  35.         len --;
  36.       }
  37.     if (*program_name == '/')
  38.         program_name ++;
  39.     return program_name;
  40. }
  41.  
  42. typedef struct dir_element {
  43.     struct dir_element *next;
  44.     char *cd_path;
  45.     char *new_path;
  46. } dir_elem;
  47.  
  48. static dir_elem *head = NULL, *tail = NULL;
  49.  
  50. int push_dir (cd_path, new_path)
  51. char *cd_path, *new_path;
  52.  
  53. {    dir_elem *tmp;
  54.  
  55.     if (head == NULL)
  56.       {    if ((head = tmp = (dir_elem *) malloc (sizeof (dir_elem))) == NULL)
  57.           {    fprintf (stderr, "Unable to allocate dir_element buffer!\n");
  58.             return FALSE;
  59.           }
  60.       }
  61.     else
  62.       {    if ((tail->next = tmp = (dir_elem *) malloc (sizeof (dir_elem))) == NULL)
  63.           {    fprintf (stderr, "Unable to allocate dir_element buffer!\n");
  64.             return FALSE;
  65.           }
  66.       }
  67.     tmp->next = NULL;
  68.     if ((tmp->cd_path = (char *) malloc (strlen (cd_path) + 1)) == NULL)
  69.       {    fprintf (stderr, "Unable to allocate cd_path of dir_element!\n");
  70.         return FALSE;
  71.       }
  72.     strcpy (tmp->cd_path, cd_path);
  73.     if ((tmp->new_path = (char *) malloc (strlen (new_path) + 1)) == NULL)
  74.       {    fprintf (stderr, "Unable to allocate new_path of dir_element!\n");
  75.         return FALSE;
  76.       }
  77.     strcpy (tmp->new_path, new_path);
  78.     tail = tmp;
  79.     return TRUE;
  80. }
  81.  
  82. dir_elem *dequeue_dir ()
  83.  
  84. {    dir_elem *tmp;
  85.  
  86.     if (head == NULL)
  87.       {    tail = NULL;
  88.         return NULL;
  89.       }
  90.     tmp = head;
  91.     head = tmp->next;
  92.     tmp->next = NULL;
  93.     return tmp;
  94. }
  95.  
  96. free_dir (dir)
  97. dir_elem *dir;
  98.  
  99. {
  100.     free (dir->cd_path);
  101.     free (dir->new_path);
  102.     free (dir);
  103. }
  104.  
  105. int proc_dir (cd_path, new_path, recurse)
  106. char *cd_path, *new_path;
  107. int recurse;
  108.  
  109. {    FILE *fp;
  110.     char line [4096], link_name [4096], new_name [4096];
  111.     char ymtrans_name [4096], resolved_name [MAXPATHLEN];
  112.     char type, elem1 [65], elem2 [2048], elem3 [2048];
  113.     int line_cnt, elem_cnt, i, j;
  114.  
  115.     sprintf (ymtrans_name, "%s/ymtrans.tbl", cd_path);
  116.     if ((fp = fopen (ymtrans_name, "rt")) == NULL)
  117.       {    fprintf (stderr, "Unable to open file %s!\n", ymtrans_name);
  118.         return FALSE;
  119.       }
  120.     line_cnt = 0;
  121.     while (fgets (line, sizeof (line), fp) != NULL)
  122.       {    line_cnt ++;
  123.         if ((strlen (line) < 17) || (line [1] != ' ') || (line [strlen (line) - 1] != '\n'))
  124.           {    fprintf (stderr, "Invalid %s file!?!\n", ymtrans_name);
  125.             exit (1);
  126.           }
  127.         type = line [0];
  128.         for (i = 2, j = 0; (line [i] != ' ') && (line [i] != '\t'); i ++, j ++)
  129.             if (isupper (line [i]))
  130.                 elem1 [j] = tolower (line [i]);
  131.             else
  132.                 elem1 [j] = line [i];
  133.         elem1 [j] = '\0';
  134.         for (i = 15, j = 0; (line [i] != '\t') && (line [i] != '\n'); i ++, j ++)
  135.             elem2 [j] = line [i];
  136.         elem2 [j] = '\0';
  137.         elem_cnt = 2;
  138.         j = 0;
  139.         if (line [i] == '\t')
  140.           {    for (i ++; line [i] != '\n'; i ++, j ++)
  141.                 elem3 [j] = line [i];
  142.             elem_cnt ++;
  143.           }
  144.         elem3 [j] = '\0';
  145.         if ((line_cnt == 1) && (strcmp (elem1, ".") == 0))
  146.             continue;
  147.         if ((line_cnt == 2) && (strcmp (elem1, "..") == 0))
  148.             continue;
  149.         sprintf (new_name, "%s/%s", new_path, elem2);
  150.         switch (type)
  151.           {    case 'F' :    sprintf (link_name, "%s/%s", cd_path, elem1);
  152.                     if (symlink (link_name, new_name) != 0)
  153.                         fprintf (stderr, "Unable to make link %s to %s!\n", elem1, elem2);
  154.                     break;
  155.  
  156.             case 'L' :    if (symlink (elem3, new_name) != 0)
  157.                         fprintf (stderr, "Unable to make link %s to %s!\n", elem1, elem3);
  158.                     break;
  159.  
  160.             case 'D' :    mkdir (new_name, 0777);
  161.                     if (recurse)
  162.                       {    sprintf (link_name, "%s/%s", cd_path, elem1);
  163.                         push_dir (link_name, new_name);
  164.                       }
  165.                     break;
  166.  
  167.             case 'M' :    mkdir (new_name, 0777);
  168.                     if (recurse)
  169.                       {    for (i = 0; elem3 [i] != '\0'; i ++)
  170.                             if (isupper (elem3 [i]))
  171.                                 elem3 [i] = tolower (elem3 [i]);
  172.                         sprintf (link_name, "%s/%s", cd_path, elem3);
  173.  
  174. #ifdef REALPATH
  175.                         realpath (resolved_name, link_name);
  176. #else
  177.                         strcpy (link_name, resolved_name);
  178. #endif
  179.  
  180.                         push_dir (resolved_name, new_name);
  181.                       }
  182.                     break;
  183.  
  184.             case '#' :    break;
  185.           }
  186.       }
  187.     fclose (fp);
  188.     return TRUE;
  189. }
  190.  
  191. int main (argc, argv)
  192. int argc;
  193. char *argv [];
  194.  
  195. {    dir_elem *cur_dir;
  196.     char cd_pathname [2048], resolved_name [MAXPATHLEN];
  197.     int recurse;
  198.  
  199.     recurse = FALSE;
  200.     if ((argc == 3) && ((strcmp (argv [1], "-r") == 0) || (strcmp (argv [1], "-R") == 0)))
  201.         recurse = TRUE;
  202.     else if (argc != 2)
  203.       {    fprintf (stderr, "Usage : %s [-r] cd_pathname\n", prog_name (argv [0]));
  204.         exit (1);
  205.       }
  206.     if (argv [argc - 1] [0] == '/')
  207.         strcpy (cd_pathname, argv [argc - 1]);
  208.     else
  209.       {    getwd (cd_pathname);
  210.         strcat (cd_pathname, "/");
  211.         strcat (cd_pathname, argv [argc - 1]);
  212.       }
  213.  
  214. #ifdef REALPATH
  215.     realpath (cd_pathname, resolved_name);
  216. #else
  217.     strcpy (resolved_name, cd_pathname);
  218. #endif
  219.  
  220.     push_dir (resolved_name, ".");
  221.     while ((cur_dir = dequeue_dir ()) != NULL)
  222.       {    proc_dir (cur_dir->cd_path, cur_dir->new_path, recurse);
  223.         free_dir (cur_dir);
  224.       }
  225.     return 0;
  226. }
  227.